package com.sugon.controller.spare;

import cn.afterturn.easypoi.entity.vo.NormalExcelConstants;
import cn.afterturn.easypoi.excel.entity.ExportParams;
import cn.afterturn.easypoi.view.PoiBaseView;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.StrUtil;
import com.sugon.annotation.AutoLog;
import com.sugon.annotation.LimitSubmit;
import com.sugon.annotation.NonBusinessParamValid;
import com.sugon.entity.SparePartEntity;
import com.sugon.entity.SparePartRequDetailEntity;
import com.sugon.entity.SparePartRequEntity;
import com.sugon.entity.vo.AddSparePartRequDetailParam;
import com.sugon.entity.vo.CancelTransitParam;
import com.sugon.modules.base.consts.BusModule;
import com.sugon.modules.sparepart.consts.SparePartNeedsPlanProgress;
import com.sugon.modules.sparepart.model.vo.SparePartRequDetailVO;
import com.sugon.modules.sparepart.service.ISparepartNeedsPlanManager;
import com.sugon.service.SparePartRequDetailService;
import com.sugon.service.SparePartRequService;
import com.sugon.service.SparePartService;
import com.sugon.utils.PageUtils;
import com.sugon.utils.Query;
import com.sugon.utils.R;
import com.sugon.utils.ShiroUtils;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.validation.BindingResult;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.FileNotFoundException;
import java.math.BigDecimal;
import java.util.List;
import java.util.Map;

/**
 * 备件需求计划明细Controller
 *
 * @author sugon
 * @date 2019-08-02 14:31:17
 */
@Controller
@RequestMapping("sparepartrequdetail")
public class SparePartRequDetailController {

    @Autowired
    private SparePartRequService sparePartRequService;
    @Autowired
    private SparePartRequDetailService sparePartRequDetailService;
    @Autowired
    private ISparepartNeedsPlanManager sparepartNeedsPlanManager;
    @Autowired
    private SparePartService sparePartService;

    /**
     * 查看列表
     * <p>
     * 数据权限
     */
    @RequestMapping("/list")
//    @RequiresPermissions("sparepartrequdetail:list")
    @ResponseBody
    public R list(@RequestParam Map<String, Object> params) {
        Query query = new Query(params);
        List<SparePartRequDetailVO> sparePartRequDetailList = sparePartRequDetailService.queryList(query);
        int total = sparePartRequDetailService.queryTotal(query);
        PageUtils pageUtil = new PageUtils(sparePartRequDetailList, total, query.getLimit(), query.getPage());
        // 只有备件需求计划ID不为空时才设置汇总金额
        String planId = MapUtil.getStr(params, "planId");
        if (StrUtil.isNotEmpty(planId)) {
            pageUtil.put("total", sparePartRequDetailService.countTotalMoney(query));
        }
        return R.ok().put("page", pageUtil);
    }

    /**
     * 从历史过程计划中选取备件需求明细中选取对应的记录添加到目标备件需求计划中
     */
    @AutoLog(value = "取消在途", busModule = BusModule.NEEDS_PLAN)
    @NonBusinessParamValid
    @RequestMapping("/addFromOldRequ")
    @RequiresPermissions("sparepartrequdetail:save")
    @ResponseBody
    public R addFromOldRequ(@Validated @RequestBody AddSparePartRequDetailParam addParam, BindingResult bindingResult) {
        // 校验目标需求计划是否存在
        SparePartRequEntity sparePartRequ = sparePartRequService.queryObject(addParam.getTargetRequId());
        if (sparePartRequ == null) {
            return R.error("目标需求计划不存在！");
        }
        List<String> requDetailIdList = addParam.getRequDetailIdList();
        for (String requDetailId : requDetailIdList) {
            // 校验需求计划是否存在
            SparePartRequDetailVO sparePartRequDetail = sparePartRequDetailService.queryObject(requDetailId);
            if (sparePartRequDetail == null) {
                return R.error("需求计划条目不存在!");
            }

            // 校验是否已添加过
            if (sparePartRequDetailService.isExists(sparePartRequ.getPlanCode(), sparePartRequDetail.getMaterialCode())) {
                return R.error("当前备件需求已存在，请勿重复添加！");
            }

            // 校验备件是否存在
            SparePartEntity sparePart = sparePartService.queryObject(sparePartRequDetail.getMaterialId());
            if (sparePart == null) {
                return R.error("备件不存在，请确认！");
            }
            // 备件必须上传图片，且不能是默认图片
            String spImagePath = sparePart.getReserve2();
            if (StrUtil.isEmpty(spImagePath) || spImagePath.contains("nopicture")) {
                return R.error("请先上传当前备件图片后，再进行添加！");
            }
            sparePartRequDetail.setTransitNum(sparePartRequDetail.getDemandNum());
            sparePartRequDetail.setInboundNum(0);
            sparePartRequDetail.setRemark(null);
            sparePartRequDetail.setIsCancelTransit(0);
            sparePartRequDetail.setOrganUser(ShiroUtils.getUserId());
            sparePartRequDetail.setApplyDept(sparePartRequ.getApplyUnit());
            sparePartRequDetail.setPlanId(sparePartRequ.getId());
            sparePartRequDetail.setBusinessCode(null);
            sparePartRequDetail.setOrderGenerateTime(null);
            sparePartRequDetail.setArriveTime(null);
            sparePartRequDetail.setActualArriveTime(null);
            // 设置备件单价
            if (sparePart.getPrice() != null) {
                sparePartRequDetail.setPlanPrice(sparePart.getPrice().doubleValue());
            }
            // 保存
            sparePartRequDetailService.save(sparePartRequDetail);
        }
        return R.ok();
    }

    /**
     * 取消在途
     */
    @AutoLog(value = "取消在途", busModule = BusModule.NEEDS_PLAN)
    @NonBusinessParamValid
    @RequestMapping("/cancelTransit")
    @RequiresPermissions("sparepartrequdetail:save")
    @ResponseBody
    public R cancelTransit(@Validated @RequestBody CancelTransitParam cancelTransitParam, BindingResult bindingResult) {
        List<String> requDetailIdList = cancelTransitParam.getRequDetailIdList();
        for (String requDetailId : requDetailIdList) {
            // 校验需求计划是否存在
            SparePartRequDetailVO sparePartRequDetail = sparePartRequDetailService.queryObject(requDetailId);
            if (sparePartRequDetail == null) {
                return R.error("需求计划条目不存在!");
            }
            // 校验是否已取消过在途数
            if (sparePartRequDetail.getIsCancelTransit() == 1) {
                return R.error(sparePartRequDetail.getMaterialCode() + "已取消在途,无需重复取消!");
            }
            sparePartRequDetail.setRemark(cancelTransitParam.getRemark());
            // 取消在途
            sparepartNeedsPlanManager.cancelTransit(sparePartRequDetail);
        }
        return R.ok();
    }

    /**
     * 查看信息
     */
    @RequestMapping("/info/{id}")
//    @RequiresPermissions("sparepartrequdetail:info")
    @ResponseBody
    public R info(@PathVariable("id") String id) {
        SparePartRequDetailVO sparePartRequDetail = sparePartRequDetailService.queryObject(id);
        return R.ok().put("sparePartRequDetail", sparePartRequDetail);
    }

    /**
     * 保存
     */
    @LimitSubmit(key = "saveSparepartrequdetail:%s")
    @AutoLog(value = "添加需求清单", busModule = BusModule.NEEDS_PLAN)
    @RequestMapping("/save")
    @RequiresPermissions("sparepartrequdetail:save")
    @ResponseBody
    public R save(@RequestBody SparePartRequDetailEntity sparePartRequDetail) {
        String planCode = sparePartRequDetail.getPlanCode();
        String planId = sparePartRequDetail.getPlanId();
        if (StrUtil.isEmpty(planCode) || StrUtil.isEmpty(planId)) {
            return R.error("备件需求计划必填！");
        }
        // 1、校验备件需求计划是否存在
        SparePartRequEntity sparePartRequ = sparePartRequService.queryObject(planId);
        if (sparePartRequ == null) {
            return R.error("备件需求计划不存在，请确认！");
        }
        // 2、只有处于编制中的需求才可以新增明细
        int progress = sparePartRequ.getProgress();
        if (progress != SparePartNeedsPlanProgress.NEW && progress != SparePartNeedsPlanProgress.NOT_PASSED && progress != SparePartNeedsPlanProgress.CANCEL) {
            return R.error("只有处于编制中的需求才可以新增明细！");
        }
        // 3、只有自己车间的人才可以添加
        if (!sparePartRequ.getOrganId().equals(ShiroUtils.getWorkshop())) {
            return R.error("只可以编制自己车间的需求计划明细！");
        }
        // 4、校验是否已添加过
        if (sparePartRequDetailService.isExists(planCode, sparePartRequDetail.getMaterialCode())) {
            return R.error("当前备件需求已存在，请勿重复添加！");
        }
        // 5、校验备件是否存在
        SparePartEntity sparePart = sparePartService.queryObject(sparePartRequDetail.getMaterialId());
        if (sparePart == null) {
            return R.error("备件不存在，请确认！");
        }
        // 6、备件必须上传图片，且不能是默认图片
        if (StrUtil.isEmpty(sparePartRequDetail.getReserve2())) {
            return R.error("备件图片必传！");
        }
        // 7、备件适用的设备类型必须指定
        if (StrUtil.isEmpty(sparePartRequDetail.getDevType()) || StrUtil.isEmpty(sparePartRequDetail.getDevTypeName())) {
            return R.error("必须指定设备类型！");
        }
        // 更新备件的图片+设备类型信息
        sparePart.setReserve2(sparePartRequDetail.getReserve2());
        sparePart.setDevType(sparePartRequDetail.getDevType());
        sparePart.setDevTypeName(sparePartRequDetail.getDevTypeName());
        sparePartService.update(sparePart);

        // 8、预计使用时间必填
        if (sparePartRequDetail.getPlaneTime() == null) {
            return R.error("预计使用时间必填！");
        }
        // 9、需求数必填
        if (sparePartRequDetail.getDemandNum() == null) {
            return R.error("需求数量必填！");
        }
        // 10、计划单价不能为空
        if (sparePartRequDetail.getPlanPrice() == null) {
            return R.error("计划单价不能为空！");
        }
        sparePartRequDetail.setOrganUser(ShiroUtils.getUserId());
        sparePartRequDetail.setApplyDept(sparePartRequ.getApplyUnit());
        boolean flag = sparePartRequDetailService.save(sparePartRequDetail) > 0;
        if (flag) {
            // 校验下备件价格是否已填写，如果没有则回填
            if (sparePart.getPrice() == null) {
                sparePart.setPrice(new BigDecimal(sparePartRequDetail.getPlanPrice()));
                sparePartService.update(sparePart);
            }
        }
        return flag ? R.ok() : R.error();
    }

    /**
     * 修改
     */
    @AutoLog(value = "修改需求清单", busModule = BusModule.NEEDS_PLAN)
    @RequestMapping("/update")
    @RequiresPermissions("sparepartrequdetail:update")
    @ResponseBody
    public R update(@RequestBody SparePartRequDetailEntity sparePartRequDetail) {
        String planCode = sparePartRequDetail.getPlanCode();
        if (StrUtil.isEmpty(planCode)) {
            return R.error("备件需求计划编码必填！");
        }
        // 1、校验备件需求计划是否存在
        SparePartRequEntity sparePartRequ = sparePartRequService.queryObjectByCode(planCode);
        if (sparePartRequ == null) {
            return R.error("备件需求计划不存在，请确认！");
        }
        // 2、只有处于编制中的需求才可以新增明细
        int progress = sparePartRequ.getProgress();
        if (progress != SparePartNeedsPlanProgress.NEW && progress != SparePartNeedsPlanProgress.NOT_PASSED) {
            return R.error("只有处于编制中的需求才可以修改明细！");
        }
        // 3、只有自己车间的人才可以添加
        String editUserCj = ShiroUtils.getWorkshop();
        if (!StrUtil.equals(editUserCj, sparePartRequ.getOrganId()) && !StrUtil.startWith(sparePartRequ.getApplyUnit(), editUserCj)) {
            return R.error("只可以编制自己车间的需求明细！");
        }
        // 4、只可以修改自己编制的需求明细
        if (!sparePartRequDetail.getOrganUser().equals(ShiroUtils.getUserId())) {
            return R.error("只可以修改自己编制的需求明细！");
        }
        // 5、校验备件是否存在
        SparePartEntity sparePart = sparePartService.queryObject(sparePartRequDetail.getMaterialId());
        if (sparePart == null) {
            return R.error("备件不存在，请确认！");
        }
        // 6、备件必须上传图片，且不能是默认图片
        if (StrUtil.isEmpty(sparePartRequDetail.getReserve2())) {
            return R.error("备件图片必传！");
        }
        // 7、备件适用的设备类型必须指定
        if (StrUtil.isEmpty(sparePartRequDetail.getDevType()) || StrUtil.isEmpty(sparePartRequDetail.getDevTypeName())) {
            return R.error("必须指定设备类型！");
        }
        // 更新备件的图片+设备类型信息
        sparePart.setReserve2(sparePartRequDetail.getReserve2());
        sparePart.setDevType(sparePartRequDetail.getDevType());
        sparePart.setDevTypeName(sparePartRequDetail.getDevTypeName());
        sparePartService.update(sparePart);
        return sparePartRequDetailService.update(sparePartRequDetail) > 0 ? R.ok() : R.error();
    }

    /**
     * 删除
     */
    @AutoLog(value = "删除需求清单", busModule = BusModule.NEEDS_PLAN)
    @RequestMapping("/delete")
    @RequiresPermissions("sparepartrequdetail:delete")
    @ResponseBody
    public R delete(@RequestBody String[] ids) {
        // 业务校验
        for (String id : ids) {
            // 如果明细不存在，则继续
            SparePartRequDetailVO sparePartRequDetail = sparePartRequDetailService.queryObject(id);
            if (sparePartRequDetail == null) {
                continue;
            }
            // 只可以修改自己编制的需求明细
            if (!sparePartRequDetail.getOrganUser().equals(ShiroUtils.getUserId())) {
                return R.error("只可以删除自己编制的需求明细！");
            }
            // 1、校验备件需求计划是否存在
            SparePartRequEntity sparePartRequ = sparePartRequService.queryObject(sparePartRequDetail.getPlanId());
            if (sparePartRequ == null) {
                return R.error("备件需求计划不存在，请确认！");
            }
            // 2、只有处于编制中的需求才可以新增明细
            int progress = sparePartRequ.getProgress();
            if (progress != SparePartNeedsPlanProgress.NEW && progress != SparePartNeedsPlanProgress.NOT_PASSED) {
                return R.error("只有处于编制中的需求才可以删除明细！");
            }
        }
        sparePartRequDetailService.deleteBatch(ids);
        return R.ok();
    }

    /**
     * 查看所有列表
     */
    @RequestMapping("/queryAll")
    @ResponseBody
    public R queryAll(@RequestParam Map<String, Object> params) {
        List<SparePartRequDetailVO> list = sparePartRequDetailService.queryList(params);
        return R.ok().put("list", list);
    }

    @AutoLog(value = "导出需求明细", busModule = BusModule.NEEDS_PLAN)
    @RequestMapping("/exportData")
    @ResponseBody
    public void export(@RequestParam Map<String, Object> queryParam, ModelMap map, HttpServletRequest request, HttpServletResponse response) throws FileNotFoundException {
        // Step.2 获取导出数据
        com.sugon.utils.MapUtil.removeEmptyValue(queryParam);
        List<SparePartRequDetailVO> sparePartRequDetailList = sparePartRequDetailService.queryList(queryParam);
        String title = "需求明细_" + DateUtil.today();
        ExportParams params = new ExportParams(title, "导出人:" + ShiroUtils.getUserRealName(), title);
        map.put(NormalExcelConstants.DATA_LIST, sparePartRequDetailList); // 数据集合
        map.put(NormalExcelConstants.CLASS, SparePartRequDetailVO.class);//导出实体
        map.put(NormalExcelConstants.PARAMS, params);//参数
        map.put(NormalExcelConstants.FILE_NAME, "领料明细_" + DateUtil.today());//文件名称
        PoiBaseView.render(map, request, response, NormalExcelConstants.EASYPOI_EXCEL_VIEW);
    }

}
